'''
目标图像的特征提取
'''
import argparse

import cv2
import os
import json
# 匹配函数
def matcher(sourcce, target_folder):

    # 获取source目录下的所有视频文件
    source_dir = sourcce  # 视频文件夹路径
    video_files = [f for f in os.listdir(source_dir) if f.endswith(('.mp4', '.avi', '.mov'))]

    if not video_files:
        print("没有找到视频文件")
        exit()

    # 获取target_folder目录下的所有图片文件
    target_image_files = [f for f in os.listdir(target_folder) if f.endswith(('.jpg', '.png', '.jpeg'))]

    if not target_image_files:
        print("没有找到目标图片")
        exit()

    # 创建ORB特征检测器
    orb = cv2.ORB_create()

    # 定义匹配器
    bf = cv2.BFMatcher(cv2.NORM_HAMMING, crossCheck=True)

    # 遍历视频文件
    for video_file in video_files:
        video_path = os.path.join(source_dir, video_file)  # 获取完整的文件路径
        print(f"正在处理视频: {video_file}")

        cap = cv2.VideoCapture(video_path)

        # 检查视频文件是否存在
        if not cap.isOpened():
            print(f"无法打开视频文件: {video_file}")
            continue  # 如果无法打开视频文件，跳过当前文件并继续下一个文件

        # 循环读取视频帧
        while cap.isOpened():
            ret, frame = cap.read()

            if not ret:
                break  # 如果读取失败，则退出循环

            # 遍历目标文件夹中的所有目标图片
            for target_image_file in target_image_files:
                target_image_path = os.path.join(target_folder, target_image_file)  # 获取完整的目标图片路径
                # print("处理目标图片:", target_image_path)

                # 读取目标图片
                target_image = cv2.imread(target_image_path)

                # 转换为灰度图
                grey_target_image = cv2.cvtColor(target_image, cv2.COLOR_BGR2GRAY)

                # 检测目标图像中的关键点和描述符
                kp_target, des_target = orb.detectAndCompute(grey_target_image, None)

                target_found = False

                # 使用YOLOv7检测到的行人框
                # person_detections 是一个检测到的行人区域 (bounding boxes)，这个数据应该来自于YOLOv7
                person_detections = [
                    [0.5, 0.5, 0.2, 0.4],  # x_center, y_center, width, height
                    [0.3, 0.3, 0.1, 0.3],  # x_center, y_center, width, height
                ]

                # 遍历检测到的行人区域
                for det in person_detections:
                    x_center, y_center, width, height = det

                    # 计算bounding box坐标
                    x_min = int((x_center - width / 2) * frame.shape[1])
                    y_min = int((y_center - height / 2) * frame.shape[0])
                    x_max = int((x_center + width / 2) * frame.shape[1])
                    y_max = int((y_center + height / 2) * frame.shape[0])

                    # 截取检测到的行人区域
                    person_image = frame[y_min:y_max, x_min:x_max]

                    # 转换为灰度图
                    person_gray = cv2.cvtColor(person_image, cv2.COLOR_BGR2GRAY)

                    # 检测行人区域的特征点
                    kp_person, des_person = orb.detectAndCompute(person_gray, None)

                    # 匹配目标图像和行人区域的特征点
                    if des_person is not None and des_target is not None:
                        matches = bf.match(des_target, des_person)

                        # 按照距离排序
                        matches = sorted(matches, key=lambda x: x.distance)

                        # 设置一个阈值，只有匹配距离足够小的情况下才认为是匹配
                        if len(matches) > 10 and matches[0].distance < 20:
                            target_found = True
                            # 假设 x_min, y_min, x_max, y_max 是匹配区域的坐标
                            coordinates = {
                                "x_min": x_min,
                                "y_min": y_min,
                                "x_max": x_max,
                                "y_max": y_max
                            }

                            # 构造 JSON 数据
                            result = {
                                "flag": True,
                                "places": coordinates
                            }

                            # 将字典转换为 JSON 字符串并打印
                            print(json.dumps(result))

                            # 在图像上绘制匹配区域
                            cv2.rectangle(frame, (x_min, y_min), (x_max, y_max), (0, 255, 0), 2)

                # 如果没有找到目标
                if not target_found:
                    continue

                # 当前的工作是，如果目标人物在视频中时，则返回一个值作为记录
                # # 显示当前帧图像
                # cv2.imshow("Detected Person with Target Match", frame)

                # 按'q'退出
                if cv2.waitKey(1) & 0xFF == ord('q'):
                    break

        # 释放视频资源
        cap.release()

    # 销毁所有窗口
    cv2.destroyAllWindows()


# 路径寻找函数，作为测试用
def find_path():
    source_image_dir = 'source'
    source_image_file = 'source/image2.jpg'
    print("路径存在吗?", os.path.isdir(source_image_dir))
    print("文件存在吗?", os.path.exists(source_image_file))
    if os.access(source_image_file, os.R_OK):
        print("具有可读权限")
    else:
        print("不具有可读权限")


if __name__ == '__main__':
    parser = argparse.ArgumentParser(description="匹配视频中的目标任务")
    parser.add_argument('--source', type=str, required=True, help="源视频文件夹路径")
    parser.add_argument('--target', type=str, required=True, help="目标图片路径")
    # 参数解析
    args = parser.parse_args()
    matcher(args.source, args.target)

    # find_path()